#include "preHeader.h"
#include "AccountMgr.h"
#include "CharacterMgr.h"

AccountMgr::AccountMgr()
{
}

AccountMgr::~AccountMgr()
{
	for (const auto& pair : m_AccountInfoMap) {
		delete pair.second;
	}
}

Account* AccountMgr::GetAccount(uint32 uid) const
{
	auto itr = m_AccountInfoMap.find(uid);
	return itr != m_AccountInfoMap.end() ? itr->second : NULL;
}

GErrorCode AccountMgr::AddAccount(GateServerSession* pSession,
	uint32 logicGsID, uint32 uid, uint32 sn)
{
	if (KickAccount(uid, SessionKickAccountRelogin) != CommonSuccess) {
		return CommonInternalError;
	}

	m_AccountInfoMap.emplace(uid, new Account(pSession, logicGsID, uid, sn));

	return CommonSuccess;
}

GErrorCode AccountMgr::KickAccount(uint32 uid, GErrorCode error)
{
	NetBuffer args;
	args << s32(error);
	return RemoveAccount(uid, SGG_KICK_ACCOUNT, args.CastBufferStringView());
}

GErrorCode AccountMgr::KillAccount(uint32 uid)
{
	return RemoveAccount(uid, SGG_KILL_ACCOUNT);
}

GErrorCode AccountMgr::RemoveAccount(
	uint32 uid, uint32 opcode, const std::string_view& args)
{
	auto itr = m_AccountInfoMap.find(uid);
	if (itr == m_AccountInfoMap.end()) {
		return CommonSuccess;
	}

	Account* pAccount = itr->second;
	m_AccountInfoMap.erase(itr);
	_defer(delete pAccount);

	NetPacket pack(opcode);
	pack << pAccount->sn;
	pack.Append(args.data(), args.size());
	pAccount->SendPacket2GateServer(pack);

	if (pAccount->IsCharacterOnline()) {
		sCharacterMgr.LogoutCharacter(pAccount, pAccount->GetCharacter());
	}

	return CommonSuccess;
}
